package com.kitty.game.activity.service.other;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.activity.ActivityDataPool;
import com.kitty.game.activity.model.product.ActivityType;
import com.kitty.game.activity.model.product.MapGuardianSet;
import com.kitty.game.activity.service.time.FightActivityHandler;
import com.kitty.game.config.NPC;
import com.kitty.game.enter.TitleInfo;
import com.kitty.game.i18n.I18nId;
import com.kitty.game.i18n.I18nIdDataPool;
import com.kitty.game.map.model.GroupMapParam;
import com.kitty.game.mirror.model.FightMirror;
import com.kitty.game.mirror.model.MirrorFightParam;
import com.kitty.game.role.model.Role;
import com.kitty.game.team.model.Team;
import com.kitty.game.utils.Const;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.mina.message.MessagePusher;
import org.nutz.json.Json;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**地图守护神处理类*/
@Component
public class MapGuardianHandler extends FightActivityHandler {
    /**最少组队人数*/
    private static final int MIN_TEAM_COUNT = 5;

    /**从传入map中获得对应数据*/
    public void loadCommonSet(Map<String ,String> commonSetMap) {
        String value = commonSetMap.get("map_guardian_set");
        List<MapGuardianSet> list = Json.fromJsonAsList(MapGuardianSet.class, value);

        Map<Integer, MapGuardianSet> map = new HashMap<>();
        Map<String, List<Integer>> sameGroupMap = new HashMap<>();
        for (MapGuardianSet mapGuardianSet : list) {
            map.put(mapGuardianSet.getNpcId(), mapGuardianSet);

            String key = mapGuardianSet.getMinLevel() + "-" + mapGuardianSet.getMaxLevel();
            List<Integer> groupList = sameGroupMap.computeIfAbsent(key, k -> new ArrayList<>(5));
            groupList.add(mapGuardianSet.getNpcId());
            mapGuardianSet.setSameGroupNpcIds(groupList);
        }

        ActivityDataPool.mapGuardianSets = map;
    }

    public MapGuardianSet getMapGuardianSet(int npcId) {
        return ActivityDataPool.mapGuardianSets.get(npcId);
    }

    @Override
    protected String getNpcContent(Role role, NPC bossNpc) {
        return bossNpc.getContent();
    }

    @Override
    protected String getNpcContentNotFight(Role role, NPC bossNpc) {
        MapGuardianSet mapGuardianSet = getMapGuardianSet(bossNpc.getId());
        if (mapGuardianSet == null) {
            /**正常不应该执行到这里*/
            new RuntimeException(MessageFormat.format("没有守护神数据， npcId: {}, npcName: {}", bossNpc.getId(), bossNpc.getName()));
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1700);
        }
        /**检测是否在战斗中*/
        if (isInFight(bossNpc)) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1700);
        }
        int teamCount = teamService.getTeamCount(role);
        if (teamCount < MIN_TEAM_COUNT) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1701, MIN_TEAM_COUNT);
        }

        Team team = teamService.getTeam(role.getRoleId());
        /**小于可挑战等级或者大于可挑战等级*/
        String names = teamService.checkMember(team, memberRole -> memberRole.getLevel() < mapGuardianSet.getMinLevel() || memberRole.getLevel() > mapGuardianSet.getMaxLevel());
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1702, names);
        }

        /**没有挑战次数时*/
        names = teamService.checkMember(team, memberRole -> SpringUtils.getActivityService().getRemainCount(memberRole, ActivityType.MAP_GUARDIAN) <= 0);
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1704, names);
        }
        /**没有参战宠物*/
        names = teamService.checkMember(team, memberRole -> SpringUtils.getPetService().getPetById(memberRole.getPetBox().getFightPetId(), memberRole) == null);
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1705, names);
        }

        //TODO 挑战对象是自己时怎么处理？？

        return null;
    }

    /**是否在战斗中，5个当中任何一个在战斗的时候，则为战斗中*/
    private boolean isInFight(NPC bossNpc) {
        MapGuardianSet mapGuardianSet = getMapGuardianSet(bossNpc.getId());
        if (mapGuardianSet == null) {return false;}

        List<Integer> sameGroupNpcIds = mapGuardianSet.getSameGroupNpcIds();
        for (int npcId : sameGroupNpcIds) {
            NPC npc = getBossNpc(npcId);
            if (npc.isInFight()) {return true;}
        }

        return false;
    }

    @Override
    protected void doStartFight(Role role, NPC bossNpc) {
        List<FightMirror> fightMirrorList = new ArrayList<>();
        MapGuardianSet mapGuardianSet = getMapGuardianSet(bossNpc.getId());
        List<Integer> sameGroupNpcIds = mapGuardianSet.getSameGroupNpcIds();
        AtomicInteger index = new AtomicInteger();

        boolean haveMirror = SpringUtils.getMirrorService().getFightMirror(bossNpc.getId()) == null ? false : true;
        teamService.memberHandle(role, memberRole -> {
            int npcId = sameGroupNpcIds.get(index.getAndIncrement());
            /**没有人挑战成功过，则根据挑战玩家数据生成镜像*/
            FightMirror tempFightMirror = haveMirror ? SpringUtils.getMirrorService().getFightMirror(npcId)
                    : SpringUtils.getMirrorService().createFightMirror(npcId, memberRole);
            fightMirrorList.add(tempFightMirror);
        });

        MirrorFightParam mirrorFightParam = new MirrorFightParam((byte) getFightType(role), bossNpc.getId(), fightMirrorList);
        SpringUtils.getMirrorService().startFight(role, mirrorFightParam);
        /**开始挑战时就增加完成次数*/
        teamService.memberHandle(role, memberRole -> SpringUtils.getActivityService().addFinishCount(memberRole, ActivityType.MAP_GUARDIAN, 1));
        bossNpc.setCreateTime(System.currentTimeMillis());
    }

    @Override
    protected int getFightType(Role role) {
        return Const.fightType_mapGuardian;
    }

    @Override
    protected NPC getBossNpc(int npcId) {
        return SpringUtils.getMapService().getNpc(npcId);
    }

    @Override
    protected void clearNpcAfterWin(Role role, NPC bossNpc) {

    }

    @Override
    public void doFightWinForTeam(Team team, FightEndEvent fightEndEvent, NPC bossNpc) {
        /**替换英雄数据*/
        MapGuardianSet mapGuardianSet = getMapGuardianSet(bossNpc.getId());
        List<Integer> sameGroupNpcIds = mapGuardianSet.getSameGroupNpcIds();

        /**收回之前称号*/
        for (int npcId : sameGroupNpcIds) {
            FightMirror fightMirror = SpringUtils.getMirrorService().getFightMirror(npcId);
            if (fightMirror == null) {continue;}
            Role oldRole = (fightMirror !=null ? SpringUtils.getPlayerService().getPlayerBy(fightMirror.getRoleMirror().getUid()) : null);
            delOldTitle(oldRole, bossNpc.getName());
        }

        AtomicInteger index = new AtomicInteger();
        teamService.memberHandle(team, memberRole -> {
            int npcId = sameGroupNpcIds.get(index.getAndIncrement());
            FightMirror fightMirror = SpringUtils.getMirrorService().createFightMirror(npcId, memberRole);
            SpringUtils.getMirrorService().addFightMirror(fightMirror);
            fightMirror.getRoleMirror().setTitle(getBossNpc(npcId).getName());
        });

        teamService.memberHandle(team, memberRole -> {
            /**更新npc外观*/
            for (int npcId : sameGroupNpcIds) {
                NPC tempBossNpc = getBossNpc(npcId);
                bossService.broadcastNpcUpdate(new GroupMapParam(memberRole), tempBossNpc);
            }

            MessagePusher.notifyMiscEx2Player(memberRole, I18nId.PMT_1706, bossNpc.getName());
        });

        /**发称号*/
        teamService.memberHandleThreadLocal(team, memberRole -> {
            SpringUtils.getRoleService().addTitle(memberRole, new TitleInfo(bossNpc.getName(), bossNpc.getName()));
        });

        /**发谣言*/
        sendNumber(team, bossNpc);
    }

    /**收回旧称号*/
    private void delOldTitle(Role role, String title) {
        if (role == null) {return ;}
        SpringUtils.getRoleService().delTitle(role, title);
    }

    /**发谣言*/
    private void sendNumber(Team team , NPC bossNpc) {
        String names = teamService.checkMember(team, memberRole -> memberRole != null);
        String msg = I18nIdDataPool.getI18nContent(I18nId.PMT_1707, names, bossNpc.getName());
        SpringUtils.getChatService().sendNumor(msg, Const.BRODCAST_MSG_TYPE_ROLE);
    }

    @Override
    protected void giveReward(Role role, FightEndEvent fightEndEvent, NPC bossNpc) {
        int exp = 4000 * role.getLevel();
        int currPetId = role.getTempCache("fight_current_pet_id", 0);
        SpringUtils.getRoleService().addExp(role, exp, role.getLevel(), currPetId);
    }

    @Override
    protected void clearNpcTimeOut(NPC npc) {

    }
}
